<template>
  <el-card>
    <el-form inline>
      <el-form-item>
        <el-input v-model="paramsState.username" placeholder="用户名" />
      </el-form-item>

      <el-button type="primary" @click="search">查询</el-button>
      <el-button type="default" @click="resetSearch">清空</el-button>
    </el-form>

    <div style="margin: 20px 0">
      <el-button type="primary" @click="showAddUser">添 加</el-button>
      <el-button type="danger" @click="revomveUsers">批量删除</el-button>
    </div>

    <el-table
      border
      stripe
      :data="tableState.users"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" />

      <el-table-column type="index" label="序号" width="80" align="center" />

      <el-table-column prop="username" label="用户名" width="150" />
      <el-table-column prop="nickName" label="用户昵称" />
      <el-table-column prop="roleName" label="角色列表" width="200" />

      <el-table-column prop="gmtCreate" label="创建时间" width="180" />
      <el-table-column prop="gmtModified" label="更新时间" width="180" />

      <el-table-column label="操作" width="200" align="center" fixed="right">
        <template v-slot="{ row }">
          <el-button
            type="info"
            size="small"
            class="el-icon-user"
            title="分配角色"
            @click="showAssignRole(row)"
          />
          <el-button
            type="primary"
            size="small"
            class="el-icon-edit"
            title="修改用户"
            @click="showUpdateUser(row)"
          />

          <el-button
            style="margin-left:10px"
            type="danger"
            size="small"
            class="el-icon-delete-solid"
            title="删除用户"
            @click="removeuser(row.id)"
          />
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      :current-page="paramsState.page"
      :page-size="paramsState.limit"
      :total="tableState.total"
      :page-sizes="[5, 10, 20, 30]"
      style="padding: 20px 0;"
      layout="prev, pager, next, jumper, ->, sizes, total"
      @current-change="getUsers"
      @size-change="getUsers(1, $event)"
    />
    <!-- 添加或修改用户弹窗 -->
    <el-dialog
      :title="userState.user.id ? '修改用户' : '添加用户'"
      :visible.sync="tableState.dialogVisible"
    >
      <el-form
        label-width="120px"
        :rules="userRules"
        ref="userFormRef"
        :model="userState.user"
      >
        <el-form-item label="用户名" prop="username">
          <el-input v-model="userState.user.username" />
        </el-form-item>
        <el-form-item label="用户昵称" prop=" nickName">
          <el-input v-model="userState.user.nickName" />
        </el-form-item>

        <el-form-item
          v-if="!userState.user.id"
          label="用户密码"
          prop="password"
        >
          <el-input v-model="userState.user.password" />
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="tableState.dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="addOrUpdate">确 定</el-button>
        </div>
      </template>
    </el-dialog>
    <!-- 设置角色弹窗 -->

    <el-dialog
      title="设置角色"
      :visible.sync="roleState.dialogRoleVisible"
      :before-close="resetRoleData"
    >
      <el-form label-width="80px">
        <el-form-item label="用户名" :value="userState.user.username">
          <el-input disabled :value="userState.user.username"></el-input>
        </el-form-item>

        <el-form-item label="角色列表">
          <el-checkbox
            v-model="roleState.checkAll"
            @change="handleCheckAllChange"
            :indeterminate="roleState.isIndeterminate"
            >全选</el-checkbox
          >
          <div style="margin: 15px 0;"></div>
          <el-checkbox-group
            v-model="roleState.userRoleIds"
            @change="handleCheckedChange"
          >
            <el-checkbox
              v-for="role in roleState.allRoles"
              :key="role.id"
              :label="role.id"
              >{{ role.roleName }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>

      <template #footer>
        <el-button type="primary" @click="assignRole">保存</el-button>
        <el-button @click="resetRoleData">取消</el-button>
      </template>
    </el-dialog>
  </el-card>
</template>

<script>
import {
  reqUserList,
  reqSaveOrUpdateUser,
  reqRemoveUser,
  reqUserRoleList,
  reqRemoveUsers,
  reqAssignUserRoleList
} from "@/api/acl/user";
export default {
  name: "User",
  data() {
    return {
      // 1.请求用户列表时需要的参数数据
      paramsState: {
        username: "",

        page: 1, // 当前页码
        limit: 5 // 每页数量
      },
      // 2.表格的相关数据
      tableState: {
        total: 0,
        users: [],
        selectedIds: [],
        dialogVisible: false,
        selectedIds: []
      },
      // 3.关于用户的相关数据
      userState: {
        user: {
          username: "",
          nickName: "",
          password: ""
        }
      },
      // 4.用户角色的相关数据
      roleState: {
        dialogRoleVisible: false,
        checkAll: false,
        isIndeterminate: false,
        userRoleIds: [],
        allRoles: []
      },
      // 5.用户添加/修改表单的校验规则
      userRules: {
        username: [
          { required: true, message: "用户名必须输入" },
          { min: 2, message: "用户名不能小于2位" }
        ],
        password: [{ required: true, validator: this.validatePassword }]
      }
    };
  },
  methods: {
    //   自定义密码校验
    validatePassword(rule, value, callback) {
      if (!value) {
        callback("密码必须输入");
      } else if (!value || value.length < 6) {
        callback("密码不能小于6位");
      } else {
        callback();
      }
    },
    //获取分页列表
    async getUsers(
      page = this.paramsState.page,
      limit = this.paramsState.limit
    ) {
      this.paramsState.page = page;
      this.paramsState.limit = limit;

      const { username } = this.paramsState;
      const re = await reqUserList(page, limit, { username });
      console.log(re);
      const { items, total } = re;
      this.tableState.users = items;
      this.tableState.total = total;
      this.tableState.selectedIds = [];
    },
    // 保存或者更新用户
    async addOrUpdate() {
      // 进行表单校验
      await this.$refs.userFormRef.value?.validate();

      const { user } = this.userState;
      if (user.username === "admin") {
        alert("admin账号不能添加或更新");
        return;
      }
      try {
        await reqSaveOrUpdateUser(user);
        this.tableState.dialogVisible = false;
        this.$message.success("保存成功");
        this.getUsers(user.id ? this.paramsState.page : 1);
        this.userState.user = {
          username: "",
          nickName: "",
          password: ""
        };
      } catch (error) {}
    },
    search() {
      this.getUsers(1);
    },
    resetSearch() {
      this.paramsState.username = "";
      this.getUsers();
    },

    // 添加按钮
    showAddUser() {
      // 清空上一次的数据
      this.userState.user = {
        username: "",
        nickName: "",
        password: ""
      };
      this.tableState.dialogVisible = true;
      // 清空上一次的校验

      this.$nextTick(() => this.$refs.userFormRef.clearValidate());
    },

    //   列表选中状态发生改变的监听回调
    handleSelectionChange(select) {
      this.tableState.selectedIds = select.map(item => item.id);
    },
    //   删除某个用户
    async removeuser(id) {
      this.$confirm(`确定删除吗?`)
        .then(async () => {
          await reqRemoveUser(id);
          this.$message.success("删除成功");
          this.getUsers(
            this.tableState.users.length === 1
              ? this.paramsState.page - 1
              : this.paramsState.page
          );
        })
        .catch(error => {
          alert("删不了");
        });
    },
    // 批量删除
    revomveUsers() {
      this.$confirm(`确定删除选中的吗?`)
        .then(async () => {
          console.log(this.tableState.selectedIds, "999");
          await reqRemoveUsers(this.tableState.selectedIds);
          this.$message.success("批量删除成功");
          this.getUsers();
        })
        .catch(error => {
          alert("删不了");
        });
    },
    // 当角色列表选项中的发生了改变
    handleCheckedChange() {
      const { userRoleIds, allRoles } = this.roleState;
      // userRoleIds.length要与allRoles.length相等并且allRoles的长度要大于0
      this.roleState.checkAll =
        userRoleIds.length === allRoles.length && allRoles.length > 0;
      // 选中的复选框的个数大于零并且选中的个数小于总个数时(不能等于，等于是全选状态)，显示半选状态
      this.roleState.isIndeterminate =
        userRoleIds.length > 0 && userRoleIds.length < allRoles.length;
    },
    // 全选按钮
    handleCheckAllChange(value) {
      // 如果当前全选，userRoleIds就是当前所有角色id的数组，否则就是空数组
      // value是个布尔值，表示当前复选框是否选中
      this.roleState.userRoleIds = value
        ? this.roleState.allRoles.map(item => item.id)
        : [];
      // 如果当前全选或者全不选时, 指定为false
      this.roleState.isIndeterminate = false;
    },
    // 修改角色按钮
    showAssignRole(user) {
      this.userState.user = user;
      this.roleState.dialogRoleVisible = true;
      this.getRoles();
    },
    // 请求用户角色列表
    async getRoles() {
      const re = await reqUserRoleList(this.userState.user?.id);
      // console.log(re, "666");

      const { allRolesList, assignRoles } = re;
      this.roleState.allRoles = allRolesList;
      this.roleState.userRoleIds = assignRoles.map(item => item.id);
      this.roleState.checkAll = allRolesList.length === assignRoles.length;
      this.roleState.isIndeterminate =
        assignRoles.length > 0 && assignRoles.length < allRolesList.length;
    },
    // 分配角色
    async assignRole() {
      const userId = this.userState.user.id;
      const roleIds = this.roleState.userRoleIds.join(",");
      await reqAssignUserRoleList(userId, roleIds);
      this.$message.success("分配角色成功");

      this.resetRoleData();
    },
    //  重置用户角色的数据
    resetRoleData() {
      Object.assign(this.roleState, {
        dialogRoleVisible: false,
        allRoles: [],
        userRoleIds: [],
        isIndeterminate: false,
        checkAll: false
      });
    },
    showUpdateUser(user) {
      this.userState.user = { ...user };
      this.tableState.dialogVisible = true;
    }
  },
  mounted() {
    this.getUsers();
  }
};
</script>

<style></style>
